﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using Omu.Awesome.Core;
using XPressify.Core;
using XPressify.Data.Helpers;

namespace XPressify.Data.CompliedQueries
{
    public class AlbumCompiledQueries
    {
        

        public static Func<Repository, Guid, Album> GetProfileAlbum
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, Album>(
                    (context, userId) => context.BaseObjects.OfType<Album>().SingleOrDefault(al => al.BaseSubject.Id == userId && al.IsProfile)
                    );
            }
        }

        public static Func<Repository, Guid, Album> GetWallAlbum
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, Album>(
                    (context, userId) => context.BaseObjects.OfType<Album>().SingleOrDefault(al => al.BaseSubject.Id == userId && al.IsWall)
                    );
            }
        }

        public static Func<Repository, Guid, IEnumerable<Album>> GetAllAlbumsOfDesc
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, IEnumerable<Album>>(
                    (context, userId) => context.BaseObjects.OfType<Album>().Where(al => al.BaseSubject.Id == userId).OrderByDescending(al => al.Created)
                    );
            }
        }

        public static Func<Repository, Guid, Album> GetAlbum
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, Album>(
                    (context, albumId) => context.BaseObjects.OfType<Album>().SingleOrDefault(al => al.Id == albumId)
                    );
            }
        }

        public static Func<Repository, Guid, Album> GetAlbumBySubjectId
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, Album>(
                    (context, subjectId) => context.BaseObjects.OfType<Album>().SingleOrDefault(al => al.BaseSubject.Id == subjectId)
                    );
            }
        }

        public static Func<Repository ,Guid, int> GetMediasNumberOf
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, int>(
                    (context, albumId) => context.BaseObjects.OfType<Media>().Where(med => med.Album.Id == albumId).Count()
                    );
            }
        }

        public static Func<Repository, Guid, bool, bool ,IEnumerable<Album>> GetAlbumsOfDesc
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, bool, bool, IEnumerable<Album>>(
                    (context, userId, friends, areFriendsOfFriends) => context.BaseObjects.OfType<Album>().Where(
                    al =>
                    al.BaseSubject.Id == userId &&
                    (al.PrivacyType == ObjectPrivacy.Everyone ||
                     (al.PrivacyType == ObjectPrivacy.FriendsOnly && friends) ||
                     (al.PrivacyType == ObjectPrivacy.FriendsOfFriends && areFriendsOfFriends))).OrderByDescending(al => al.Created)
                    );
            }
        }

        public static Func<Repository, Guid, Guid> GetAlbumSubjectId
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, Guid>(
                    (context, albumId) => context.BaseSubjects.OfType<User>().FirstOrDefault(usr => usr.BaseObjects.Select(sub => sub.Id) .Contains(albumId)).Id
                    );
            }
        }


        public static Func<Repository, Guid, BaseSubject> GetAlbumSubject
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, BaseSubject>(
                    (context, albumId) => context.BaseSubjects.FirstOrDefault(usr => usr.BaseObjects.Select(sub => sub.Id).Contains(albumId))
                    );
            }
        }

        public static Func<Repository, Guid, Album> GetAlbumByMediaId
        {
            get
            {
                return CompiledQuery.Compile<Repository, Guid, Album>(
                    (context, mediaId) => context.BaseObjects.OfType<Album>().SingleOrDefault(al => al.Medias.Select(med => med.Id).Contains(mediaId))
                    );
            }
        }

    }
}